<template>
    <!-- 三级列表 -->
    <Category :disabled="!isShowList"/>

    
    <el-card  shadow="always" :body-style="{ padding: '20px' }" :style="{marginTop: '40px'}">

        <!-- 商品属性表格 -->
        <template #header v-if="isShowList">
            <el-button  type="primary" :disabled="!category3Id"  @click="addAttr" :icon="CirclePlusFilled">新增属性</el-button>
        </template>
        <el-table border stripe :data="tableData" v-if="isShowList">
            <el-table-column  type="index" width="80" label="序号" align="center"/>
            <el-table-column  label="属性名称" width="150" prop="attrName"></el-table-column>
            <el-table-column  label="属性值名称列表" v-slot="{row}">
                <el-tag 
                    type="success" 
                    size="default" 
                    v-for="item in row.attrValueList" 
                    :key="item.id"
                    :style="{marginRight: '10px'}"
                >{{item.valueName}}</el-tag>
            </el-table-column>
            <el-table-column  label="操作" width="150">
                <template #="{row}">
                    <el-button type="warning" size="default" :icon="Edit" @click="upDateAttr(row)"></el-button>
                    <!-- 气泡确认框 -->
                    <el-popconfirm title="你确定要删除吗?" @confirm="deleteAttr(row)">
                        <template #reference >
                            <el-button type="danger" size="default" :icon="DeleteFilled" ></el-button>
                        </template>
                    </el-popconfirm>  
                </template>
            </el-table-column>
        </el-table>

        <!-- 添加或者修改属性页面 -->
        <div v-else>
            <el-form :inline="true" :style="{marginBottom: '8px'}">
                <el-form-item label="属性名">
                    <el-input placeholder="输入属性名" v-model="newAttr.attrName"></el-input>
                </el-form-item>
            </el-form>
            <div>
                <el-button v-model="newAttr.attrName" :disabled="!newAttr.attrName.trim()"  type="primary"  @click="addAttrValue">添加属性值</el-button>
                <el-button  @click="isShowList = true">取消</el-button>
            </div>
            <el-table :data="newAttr.attrValueList" border stripe :style="{marginTop: '30px' , marginBottom: '30px'}">
                <el-table-column type="index" width="120" label="序号" align="center"/>
                <el-table-column label="属性值名称" >
                    <template #="{row , $index}">
                        <el-input  
                            ref="inputEle"
                            v-if="row.isEdit" 
                            @blur="toLook(row , $index)" 
                            v-model="row.valueName" 
                            placeholder="请输入新增的属性值名称"  
                            @focus="saveOldValue(row)"
                        ></el-input>
                        <span 
                            v-else 
                            @click="toEdit(row)" 
                            :style="{display: 'inline-block' , width: '80%'}"  
                        >{{row.valueName}}</span>
                    </template>
                </el-table-column>
                <el-table-column label="操作">
                    <template #="{$index}">
                        <!-- 气泡确认框 -->
                        <el-popconfirm title="你确定要删除吗?" @confirm="deleteAttrValue($index)">
                        <template #reference >
                            <el-button type="danger" icon="ele-Delete"></el-button>
                        </template>
                        </el-popconfirm>  
                    </template>
                </el-table-column>
            </el-table>
            <div>
                <el-button 
                    type="primary" 
                    :disabled="newAttr.attrValueList.length<=0 || !newAttr.attrName.trim()"  
                    @click="addOrUpdateAttr"
                >保存</el-button>
                <el-button  @click="isShowList = true">取消</el-button>
            </div>    
        </div>

    </el-card>

    

</template>

<script lang="ts">
import { defineComponent } from "vue";
import { storeToRefs } from "pinia";
import { ElMessage } from "element-plus";

export default defineComponent({
    name: "Attr",
});
</script>

<script setup lang="ts">
import { Edit , DeleteFilled , CirclePlusFilled } from "@element-plus/icons-vue"  
import {ref , watch , nextTick} from "vue"
import useAttrStore from "@/stores/attr";
import type {attrListType , attrListItemType , attrValueListType} from "@/api/attr"
import {requestAttrList , requestUpdateOrAddAttr , requestDeleteAttr} from "@/api/attr"
import cloneDeep from "lodash/cloneDeep";

const attrStore = useAttrStore()
const {category1Id , category2Id , category3Id} = storeToRefs(attrStore)


//1.请求商品列表逻辑
//定义表格数据
const tableData = ref<attrListType>([])
//封装请求商品属性列表的函数
const getAttrList = async () => {
    //发送请求
    const result = await requestAttrList(
        category1Id.value as number,
        category2Id.value as number,
        category3Id.value as number
      )
    //请求成功把数据赋值给组件中
    tableData.value = result
}
//监听category3Id的改变请求商品属性列表
watch(category3Id , async (newValue) => {
    //判断改变后3Id为空把数组数据清空
    if (!newValue) {
        tableData.value = [];
        return;
    }
    try {
        //请求送属性列表
        getAttrList()
    }catch(e) {
        ElMessage.error("请求商品属性列表失败!!!")
    }

} , {immediate: true})


//2.添加属性逻辑
//定义属性控制添加属性和修改属性页面的显示隐藏
const isShowList = ref(true)
//定义数据保存一条要添加的属性
const newAttr = ref<attrListItemType>({
    attrName: "",
    categoryId: category3Id.value as number,
    categoryLevel: 3,
    attrValueList: []
})

//2.1点击添加属性的回调
const addAttr = () => {
    //显示页面
    isShowList.value = false
    //把之前的数据清空
    newAttr.value = {
        attrName: "",
        categoryId: category3Id.value as number,
        categoryLevel: 3,
        attrValueList: []
    }
}
//2.2点击修改属性的回调
const upDateAttr = (row: attrListItemType) => {
    //显示页面
    isShowList.value = false
    //给回填的数据添加一个数据，渲染的时候，展示span标签
    const newRow = cloneDeep(row)
    newRow.attrValueList.forEach((item) => {
        item.isEdit = false
    })
    //数据回填
    newAttr.value = newRow
}

//2.3点击添加属性值的回调函数
const  addAttrValue = () => {
    //先创建一个属性值数据
    const newAttrValue = ref<attrValueListType>({
        valueName: "",   //属性值的名称
        attrId: newAttr.value.id, //属性值所在的属性的id，现在是没有的,但是修改的时候需要，我们就直接定义
        isEdit: true //添加属性值数据的时候，这个数据代表是新增模式，(添加一定是新增模式)
    })
    //每次点击添加属性值就往属性列表中的 属性值列表中插入一条属性值数据
    newAttr.value.attrValueList.push(newAttrValue.value)
    //新增input元素后获取以下焦点
    nextTick(() => {
        inputEle.value.focus()
    })
}

//获取input元素
const inputEle = ref()
//2.5切换到编辑模式的逻辑
const toEdit = (row: attrValueListType) => {
    //隐藏span，显示input
    row.isEdit = true
    //切换到编辑模式后就获取焦点
    //让当前的表单自动获取焦点(操作真实DOM的时候,看情况要放在nextTick中,等DOM加载完成才能执行)
    nextTick(() => {
        inputEle.value.focus()
    })
}

//定义一个全局变量保存上一次输入框的值
let oldAttrValueName = ""
//获取焦点保存到旧值
const saveOldValue = (row: attrValueListType) => {
    oldAttrValueName = row.valueName
}

//2.6切换到查看模式的逻辑
const toLook = (row: attrValueListType , index: number) => {
    //失去焦点切换到查看模式
    row.isEdit = false

    //2.6.1判断输入的内容是否为空
    if(!row.valueName.trim()){
            //如果输入为空，并且旧值也为空，说明用户是新增属性值，并且没填数据，我们就把这条数据删除
        if(!oldAttrValueName){
            newAttr.value.attrValueList.splice(index , 1)
        }else{
            //如果输入为空，但是旧值有数据，则说名用户把旧值删了,我们在把旧值还给用户
            row.valueName = oldAttrValueName
        }
    }

    //判断输入的内容是否重复,如果重复，则恢复(用输入的内容和数组中其他所有的内容比较)
    let isRepeat = newAttr.value.attrValueList.some((item) => {
        //如果自己比较自己的时候，跳过
        if(item === row){
            return 
        }
        return item.valueName === row.valueName
    })

    //2.6.2如果重复判断有没有旧值
    if(isRepeat){
        if(!oldAttrValueName){
            //如果没有旧值，说明用户是新增了一个重复的数据，我们把它删除
            newAttr.value.attrValueList.splice(index , 1)
        }else{
            //如果有旧值，则说明用户修改了一个重复的，我们把它还原即可
            row.valueName = oldAttrValueName
        }
    }

    //统一失去焦点后 清空旧值
    oldAttrValueName = ""

}


//2.7点击删除某个属性值的回调
const deleteAttrValue = ($index: number) => {
    newAttr.value.attrValueList.splice($index , 1)
}

//2.8点击保存的回调
const addOrUpdateAttr = async() => {
    //因为按钮判断过，能点击旧说有只可以提交
    try {
        //发送修改或添加请求
        await requestUpdateOrAddAttr(newAttr.value)
        //成功提示
        ElMessage.success(newAttr.value.id? '修改成功' : '添加成功')
        //添加成功回到商品列表页面
        isShowList.value = true
        //重新请求商品属性列表
        getAttrList()
    } catch (error) {
        ElMessage.error(newAttr.value.id? '修改失败' : '添加失败')
    }
}

//2.9点击删除某一条属性的回调
const deleteAttr = async (row: attrListItemType) => {
    try {
        await  requestDeleteAttr(row.id as number)
        //成功提示
        ElMessage.success("删除商品属性成功!")
        //重新请求商品属性列表
        getAttrList()
    } catch (error) {
        ElMessage.error("删除商品属性失败!")
    }
}


</script>